package com.jack.xmlparser.parser;

import java.io.InputStream;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.jack.xmlparser.iui.BaseParser;
import com.jack.xmlparser.util.Book;

public class DomParserForBook implements BaseParser {

	@Override
	public List<Object> parserToObject(InputStream is) {
		// TODO Auto-generated method stub
		List<Object> mBooks = new ArrayList<Object>();
		try {
			DocumentBuilderFactory mFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder mBuilder = mFactory.newDocumentBuilder();
			Document mDoc = mBuilder.parse(is);
			Element mRootElement = mDoc.getDocumentElement();
			NodeList mItems = mRootElement.getElementsByTagName("book");
			if (mItems != null && mItems.getLength() > 0) {
				for (int i = 0; i < mItems.getLength(); i++) {
					Book mBook = new Book();
					Node mNode = mItems.item(i);
					if (mNode.hasAttributes()) {
						NamedNodeMap mAttri = mNode.getAttributes();
						Node mAttriNode = mAttri.getNamedItem("id");
						mBook.setId(Integer.parseInt(mAttriNode.getNodeValue()));
					}
					NodeList mChlidItem = mNode.getChildNodes();
					if (mChlidItem != null && mChlidItem.getLength() > 0) {
						for (int j = 0; j < mChlidItem.getLength(); j++) {
							Node mChildNode = mChlidItem.item(j);
							String mChildNodeName = mChildNode.getNodeName();
							if (mChildNodeName.equals("name")) {
								mBook.setName(mChildNode.getFirstChild().getNodeValue());
							} else if (mChildNodeName.equals("price")) {
								mBook.setPrice(Float.parseFloat(mChildNode.getFirstChild().getNodeValue()));
							}
						}
					}
					mBooks.add(mBook);
				}
			}
			return mBooks;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			mBooks = null;
			return null;
		}
	}

	@Override
	public String parserToXml(List<Object> list) {
		// TODO Auto-generated method stub
		try {
			DocumentBuilderFactory mFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder mBuilder = mFactory.newDocumentBuilder();
			Document mDoc = mBuilder.newDocument();
			
			Element mRootElement = mDoc.createElement("books");
			
			for (Object object : list) {
				if (object instanceof Book) {
					Book mBook = (Book) object;
					
					Element mBookElement = mDoc.createElement("book");
					mBookElement.setAttribute("id", String.valueOf(mBook.getId()));
					
					Element mNameElement = mDoc.createElement("name");
					mNameElement.setTextContent(mBook.getName());
					mBookElement.appendChild(mNameElement);
					
					Element mPriceElement = mDoc.createElement("price");
					mPriceElement.setTextContent(String.valueOf(mBook.getPrice()));
					mBookElement.appendChild(mPriceElement);
					
					mRootElement.appendChild(mBookElement);
				}
			}
			mDoc.appendChild(mRootElement);
			
			TransformerFactory mTransFactory = TransformerFactory.newInstance();
			Transformer mTransformer = mTransFactory.newTransformer();
			mTransformer.setOutputProperty(OutputKeys.ENCODING, "utf-8");
			mTransformer.setOutputProperty(OutputKeys.INDENT, "yes");
			mTransformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
			
			StringWriter mWriter = new StringWriter();

			DOMSource mSource = new DOMSource(mDoc);
			StreamResult mResult = new StreamResult(mWriter);
			mTransformer.transform(mSource, mResult);
			
			return mWriter.toString();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
	}

}
